package com.zhwei.gulimall.order.config;

import com.rabbitmq.client.Channel;
import com.zhwei.gulimall.order.entity.OrderEntity;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Configuration
public class MyMQConfig {

    /**
     * 容器中 binging,qUEUE,eXCHANGE都回会自动创建,一旦创建完成队列，如果修改属性，是不变的，需要删除队列重新创建
     * 创建延迟队列
     * @return
     */
    @Bean
    public Queue orderDelayQueue(){

        //String name, boolean durable, boolean exclusive, boolean autoDelete,
        // @Nullable Map<String, Object> arguments
        // ctrl+shift+enter 自动结束该行
        /*x-dead-letter-exchange: order-event-exchange  # 表示死信会找uesr.order.exchage
        x-dead-letter-routing-key: order.release.order : # 表示指定死信路由键
        x-message-ttl: 60000  # 表示消息的存活是1分钟*/
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange","order-event-exchange");
        arguments.put("x-dead-letter-routing-key","order.release.order");
        arguments.put("x-message-ttl", 60000);
        Queue queue = new Queue("order.delay.queue", true, false, false, arguments);
        return queue;
    }

    /**
     * 创建死信队列：就是在延迟队列order.delay.queue 释放之后 进入队列order.release.order.queue
     * @return
     */
    @Bean
    public Queue orderReleaseOrderQueue(){
        Queue queue = new Queue("order.release.order.queue", true, false, false);
        return queue;
    }

    /**
     * 创建一个topic的交换机，因为这个交换机可以路由到延迟队列，也可能路由到死信队列，这种要路由到多个队列的一般用topic交换机
     * @return
     */
    @Bean
    public Exchange orderEventExchange(){

        //String name, boolean durable, boolean autoDelete, Map<String, Object> arguments
        //这个也其实一个普通的交换机，只是类型是topic
        return  new TopicExchange("order-event-exchange", true, false);
    }

    @Bean
    public Binding orderCreateOrder(){
        //String destination, Binding.DestinationType destinationType, String exchange,
        // String routingKey, @Nullable Map<String, Object> arguments
        return new Binding("order.delay.queue", Binding.DestinationType.QUEUE,
                "order-event-exchange", "order.create.order", null);
    }
    @Bean
    public Binding orderReleaseOrder(){

        return new Binding("order.release.order.queue", Binding.DestinationType.QUEUE,
                "order-event-exchange", "order.release.order", null);
    }
    /**
     * 测试监听，当然这个方法不一定是要放在这个类里面的哈，可以放到其他类中，这里只是方便测试
     */
    @RabbitListener(queues = {"order.release.order.queue"} )
    public void listenReleaseQueue(Message message, OrderEntity entity, Channel channel){
        System.out.println("接收到过期订单：准备关闭订单："+entity.getOrderSn()+
                "\n原来订单创建时间："+entity.getModifyTime() +
                "\n订单接收到的时间:" + new Date());

        //消息确认
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
